package io.techery.progresshint.addition;

import io.techery.progresshint.ProgressHintDelegate;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Slider;
import ohos.agp.utils.Point;

import ohos.multimodalinput.event.TouchEvent;

public class VerticalProgressHintDelegate extends ProgressHintDelegate {
    /**
     * 方向CW
     */
    private static final int CW = 1;
    /**
     * 方向CCW
     */
    private static final int CCW = 0;

    private int[] tmpCoords;

    /**
     * VerticalProgressHintDelegate Instance
     *
     * @param seekBar seekBar
     * @param attrSet attrSet
     * @param styleName styleName
     */
    public VerticalProgressHintDelegate(Slider seekBar, AttrSet attrSet, String styleName) {
        super(seekBar, attrSet, styleName);
    }

    @Override
    protected Point getHintDragCoordinates(TouchEvent event) {
        tmpCoords = mSeekBar.getLocationOnScreen();
        float floatX;
        float floatY = mSeekBar.getBottom();
        switch (getOrientation()) {
            case CW:
                floatX = event.getPointerScreenPosition(event.getIndex()).getY() - tmpCoords[1];
                break;
            case CCW:
                floatX = tmpCoords[1] - event.getPointerScreenPosition(event.getIndex()).getY();
                break;
            default:
                throw new IllegalStateException("This widget orientation is not supported");
        }
        return new Point(floatX, floatY);
    }

    @Override
    protected Point getFixedHintOffset() {
        int xOffset = getHorizontalOffset();
        int yOffset = getVerticalOffset(mSeekBar.getMax() / 2);
        return new Point(xOffset, yOffset);
    }

    @Override
    protected Point getFollowHintOffset() {
        int xOffset = getHorizontalOffset();
        int yOffset = getVerticalOffset(mSeekBar.getProgress());
        return new Point(xOffset, yOffset);
    }

    private int getHorizontalOffset() {
        switch (getOrientation()) {
            case CW:
                return mPopupOffset;
            case CCW:
                return mSeekBar.getHeight() + mPopupOffset;
            default:
                throw new IllegalStateException("This widget orientation is not supported");
        }
    }

    private int getVerticalOffset(int progress) {
        int followPosition = getFollowPosition(progress);
        int yOddOffset;
        switch (getOrientation()) {
            case CW:
                yOddOffset = mPopupView.getEstimatedHeight() / 2 + mSeekBar.getHeight() / 2 - 15;
                return followPosition - yOddOffset;
            case CCW:
                yOddOffset = mPopupView.getEstimatedHeight() / 2 + mSeekBar.getHeight() * 2;
                return -followPosition - yOddOffset;
            default:
                throw new IllegalStateException("This widget orientation is not supported");
        }
    }

    private int getOrientation() {
        return (int) (mSeekBar.getRotation() / 90f) == 1 ? CW : CCW;
    }

    @Override
    public boolean isWidgetFullyVisible(Component container) {
        int relativeTop = ViewUtil.getRelativeTop(mSeekBar, container);
        int followPosition = getFollowPosition(
                getPopupStyle() == POPUP_FOLLOW ? mSeekBar.getProgress() : mSeekBar.getMax() / 2);

        boolean fitsTop;
        boolean fitsBottom;
        switch (getOrientation()) {
            case CW:
                fitsTop = container.getScrollValue(Component.AXIS_Y) <
                        relativeTop + followPosition + mSeekBar.getPaddingLeft() - mPopupView.getHeight() / 2;
                fitsBottom = container.getHeight() + container.getScrollValue(Component.AXIS_Y) >
                        relativeTop + followPosition + mSeekBar.getPaddingRight() + mPopupView.getHeight() / 2;
                break;
            case CCW:
                fitsTop = relativeTop + (mSeekBar.getWidth() - followPosition) - mPopupView.getHeight() >
                        container.getScrollValue(Component.AXIS_Y);
                int bottom = container.getHeight() + container.getScrollValue(Component.AXIS_Y);
                bottom = bottom + followPosition + mSeekBar.getPaddingLeft();
                fitsBottom = bottom > relativeTop + mSeekBar.getWidth() + mPopupView.getHeight() / 2;
                break;
            default:
                throw new IllegalStateException("This widget orientation is not supported");
        }
        return fitsTop && fitsBottom;
    }
}
